import uuid

from sqlalchemy import Column, Integer, String, Boolean, Text, UniqueConstraint, ForeignKey, quoted_name, event, \
    BigInteger, Index
from sqlalchemy.orm import relationship, reconstructor
from sqlalchemy.sql import expression
from models import Base
import json


class Schema(Base):
    __tablename__ = "schema"

    id = Column(Integer, primary_key=True, autoincrement=True)
    schema_id = Column(String(48), nullable=False)
    name = Column(String(48), nullable=False)
    desc = Column(Text)
    field = relationship('Field', back_populates='schema')

    deleted = Column(Boolean, nullable=False, server_default=expression.false())


class Field(Base):
    __tablename__ = 'field'
    __table_args__ = (UniqueConstraint('schema_id', 'name'),)

    id = Column(Integer, primary_key=True, autoincrement=True)
    field_id = Column(String(48), nullable=False)
    name = Column(String(48), nullable=False)
    meta = Column(Text, nullable=False)
    # ref_id = Column(Integer, ForeignKey('field.id', ondelete='CASCADE'))
    # ref = relationship('Field', uselist=False, cascade="all, delete")
    schema_id = Column(Integer, ForeignKey('schema.id'), nullable=False)
    schema = relationship('Schema', back_populates='field')
    desc = Column(Text)
    deleted = Column(Boolean, nullable=False, default=False)

    @reconstructor
    def init_on_load(self):
        """ 在从数据库加载对象时处理所有字段 """
        self.meta = json.loads(self.meta)


class Entity(Base):
    __tablename__ = 'entity'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    entity_id = Column(String(64), unique=True, nullable=False, server_default=uuid.uuid4().hex)
    schema_id = Column(Integer, ForeignKey('schema.id'), nullable=False)
    schema = relationship('Schema')

    deleted = Column(Boolean, nullable=False, server_default=expression.false())


class Value(Base):
    __tablename__ = quoted_name('value', quote=True)
    __table_args__ = (
        UniqueConstraint('entity_id', 'field_id', name='uq_entity_field'),
        Index('idx_entity_field', 'entity_id', 'field_id'),
    )

    # __table_args__ = (UniqueConstraint('entity_id', 'field_id', name='uq_entity_field', ),)

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    value = Column(Text, nullable=False, quote=True, name='value')
    field_id = Column(Integer, ForeignKey('field.id'), nullable=False)
    entity_id = Column(BigInteger, ForeignKey('entity.id'), nullable=False)
    entity = relationship('Entity')
    field = relationship('Field')

    deleted = Column(Boolean, nullable=False, server_default=expression.false())


# 创建事件监听器，用于在保存前转换 Python 对象为 JSON 字符串
@event.listens_for(Field, 'before_insert')
@event.listens_for(Field, 'before_update')
def before_save(mapper, connection, target):
    """ 在插入或更新之前处理字段 """
    if isinstance(target.meta, (dict, list)):
        # 将 Python 对象转换为 JSON 字符串
        target.meta = json.dumps(target.meta)
